16. Exercise: Adding a ViewModel
L6 31 Add A ViewModel SC
Update Note:
At timestamp 03:00 in the video above, theonCreateView()function ofSleepTrackerFragment.kt,…
- demonstrates a now deprecated class ViewModelProviders as
val sleepTrackerViewModel = ViewModelProviders.of( this, viewModelFactory).get(SleepTrackerViewModel::class.java).
Instead, please use the ViewModelProvider as shown in the instructions below.
- The way to set the binding lifecycle to itself has changed from
binding.setLifecycleOwner(this)tobinding.lifecycleOwner = this.
Now it’s your turn to complete this exercise yourself.
In this step, you'll look at the SleepTrackerViewModel and SleepTrackerViewModelFactory classes, then create a view model in the SleepTrackerFragment and add it to data binding and the layout.
In SleepTrackerViewModel
In the
sleeptrackerpackage, openSleepTrackerViewModel.kt.Inspect the provided
SleepTrackerViewModelclass definition that extendsAndroidViewModel().This class is the same as
ViewModel, but it takes the application context as a parameter and makes it available as a property. You are going to need this later on to access resources.The
ViewModelneeds access to the data in the database, so pass in an instance of theSleepDatabaseDao. And then pass this up to the superclass as well:
class SleepTrackerViewModel(
val database: SleepDatabaseDao,
application: Application) : AndroidViewModel(application) {
}
In SleepTrackerViewModelFactory
In the
sleeptrackerpackage, openSleepTrackerViewModelFactory.kt.The provided
SleepTrackerViewModelFactorytakes the same argument as theViewModeland extendsViewModelProvider.Factory.Inside the factory, the code overrides
create(), which takes any class type as an argument and returns aViewModel.In the body of
create(), we check that there is aSleepTrackerViewModelclass available, and if there is, return an instance of it. Otherwise, we throw an exception.Tip: This is mostly boilerplate code, so it looks very similar to what you created in the previous lesson, and you can reuse it for future view model factories.
SleepTrackerFragment
- In the
SleepTrackerFragment, inonCreateView(), get a reference to the application context.
val application = requireNotNull(this.activity).application
Define a
dataSource.To get a reference to the DAO of the database, use
SleepDatabase.getInstance(application).sleepDatabaseDao.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
Create an instance of the
viewModelFactory.You'll need to pass in
dataSourceas well asapplication.
val viewModelFactory = SleepTrackerViewModelFactory(dataSource, application)
Get a reference to the
SleepTrackerViewModel.To the
ViewModelProvider, specify to use theviewModelFactoryand get an instance ofSleepTrackerViewModel::class.java.
val sleepTrackerViewModel =
ViewModelProvider(
this, viewModelFactory).get(SleepTrackerViewModel::class.java)
- Your finished code in the
SleepTrackerFragmentshould look like this:
// Create an instance of the ViewModel Factory.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
val viewModelFactory = SleepTrackerViewModelFactory(dataSource, application)
// Get a reference to the ViewModel associated with this fragment.
val sleepTrackerViewModel =
ViewModelProvider(
this, viewModelFactory).get(SleepTrackerViewModel::class.java)
Data Binding for ViewModel
In
SleepTrackerFragmentinsideonCreateView():Set the current activity as the lifecycle owner of the binding.
binding.lifecycleOwner = this
In
fragment_sleep_tracker.xml:Inside the
<data>block, create a<variable>that references theSleepTrackerViewModelclass.
<data>
<variable
name="sleepTrackerViewModel"
type="com.example.android.trackmysleepquality.sleeptracker.SleepTrackerViewModel" />
</data>
In
SleepTrackerFragmentinsideonCreateView():Assign the
sleepTrackerViewModelbinding variable to thesleepTrackerViewModel.
binding.sleepTrackerViewModel = sleepTrackerViewModel
- Finally, as always, make sure your code builds and runs without errors.
If you want to start at this step, you can download this exercise from: Step.04-Exercise-Add-ViewModel.
You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.
Once you’re done, you can check your solution against the solution we’ve provided here: Step.04-Solution-Add-ViewModel, or using this git diff.
Task Feedback:
Great!
Reference documentation